Task 305: .IFB File Format
Task 305: .IFB File Format
File Format Specifications for .IFB
The .IFB file format is the Oracle Siebel Enterprise Integration Manager (EIM) configuration file. It is used to define processes for data import, export, delete, merge, or shell operations in Siebel applications. The file is a structured text file with sections and key-value parameters to control EIM tasks. It supports ASCII or Unicode encoding and follows an INI-like syntax with specific rules for sections, parameters, comments, and line continuation. The default file is named default.ifb and is typically located in the Siebel Server/admin directory. Detailed syntax and parameters are based on Oracle's EIM Administration Guide.
- List of all the properties of this file format intrinsic to its file system:
- File extension: .ifb
- File type: Text configuration file
- Encoding: ASCII or Unicode (binary)
- Structure: Section-based, with header section followed by process sections
- Section syntax: Sections start with [Section Name] on a new line
- Parameter syntax: KEY = VALUE (case-sensitive, with optional spaces around =)
- Comment character: ; (semicolon, for inline or full-line comments)
- Line continuation: \ (backslash at end of line, no trailing space)
- Allowed characters in section names: Alphanumeric, #, _, :, -, $, %, /, +
- Required header section: [Siebel Interface Manager]
- Parameter categories: Header parameters, generic process parameters, import-specific, export-specific, delete-specific, merge-specific
- All possible parameters (properties):
- Header: CONNECT, LOG TRANSACTIONS TO FILE, PASSWORD, PROCESS, TABLEOWNER, USERNAME, CURRENT_DATETIME, CURRENT_USER, IfbFileName, LANGUAGE, MAX_NEST_SUBST, ODBC_DATA_SOURCE, ROOT_DIR, SIEBEL_FILE_DIR, TABLE_OWNER, TraceFlags
- Generic process: BATCH, COMMIT EACH PASS, COMMIT EACH TABLE, IGNORE BASE TABLES, INCLUDE, LOG TRANSACTIONS, ONLY BASE TABLES, ROLLBACK ON ERROR, SESSION SQL, SKIP BU_ID DEFAULT, TABLE, TRANSACTION SQL, TYPE, UPDATE STATISTICS, USE ESSENTIAL INDEX HINTS, USE INDEX HINTS, SET BASED LOGGING, USE SYNONYMS
- Import-specific: ATTACHMENT DIRECTORY, COMMIT OPERATIONS, DEFAULT COLUMN, FILTER QUERY, FIXED COLUMN, IGNORE BASE COLUMNS, INSERT ROWS, MISC SQL, NET CHANGE, ONLY BASE COLUMNS, TRIM SPACES, UPDATE ROWS
- Export-specific: EXPORT ALL ROWS, EXPORT MATCHES, CLEAR INTERFACE TABLE, USING SYNONYMS
- Delete-specific: CLEAR INTERFACE TABLE, DELETE ALL ROWS, DELETE EXACT, DELETE MATCHES, DELETE ROWS, DELETE SKIP PRIMARY, CASCADE DELETE ONLY
- Merge-specific: MERGE ROWS, SURVIVOR ROW, MERGE DUPLICATES, UPDATE ROWS, IF_ROW_MERGE_ID, ROW_ID, IF_ROW_STAT
- Two direct download links for files of format .IFB:
- https://crackingsiebel.wordpress.com/wp-content/uploads/2012/03/extractoptyattachments-ifb.docx (This is a .docx file containing an embedded .ifb file for extracting attachments via EIM; open it to access the .ifb content.)
- No second direct .ifb download link was found in public sources; however, a sample .ifb can be copied from Oracle's documentation page: https://docs.oracle.com/cd/F14158_02/books/EIMAdm/eim-examples-of-common-usage.html (the sample is for importing employees and can be saved as .ifb).
- Ghost blog embedded HTML JavaScript for drag-and-drop .IFB file dump:
Drag and drop .IFB file here
- Python class for .IFB file handling:
import configparser
import os
class IFBHandler:
def __init__(self, filepath):
self.filepath = filepath
self.config = configparser.ConfigParser(allow_no_value=True, delimiters=('=',))
self.config.optionxform = str # Preserve case
self.properties = {}
def read(self):
with open(self.filepath, 'r', encoding='utf-8') as f:
content = f.read()
# Handle line continuations
content = content.replace('\\\n', '')
with open('temp.ifb', 'w', encoding='utf-8') as temp:
temp.write(content)
self.config.read('temp.ifb')
os.remove('temp.ifb')
for section in self.config.sections():
for key in self.config[section]:
full_key = f"{section}.{key}" if section != 'DEFAULT' else key
self.properties[full_key] = self.config[section][key]
self.print_properties()
def print_properties(self):
print("Properties:")
for key, value in self.properties.items():
print(f"{key}: {value}")
def write(self, new_properties):
for full_key, value in new_properties.items():
if '.' in full_key:
section, key = full_key.split('.', 1)
if not self.config.has_section(section):
self.config.add_section(section)
self.config.set(section, key, value)
else:
self.config.set('DEFAULT', full_key, value)
with open(self.filepath, 'w', encoding='utf-8') as f:
self.config.write(f)
# Example usage:
# handler = IFBHandler('example.ifb')
# handler.read()
# handler.write({'Siebel Interface Manager.PROCESS': 'NewValue'})
- Java class for .IFB file handling:
import java.io.*;
import java.util.*;
public class IFBHandler {
private String filepath;
private Map<String, String> properties = new HashMap<>();
public IFBHandler(String filepath) {
this.filepath = filepath;
}
public void read() throws IOException {
properties.clear();
try (BufferedReader reader = new BufferedReader(new FileReader(filepath))) {
String line;
String currentSection = "";
while ((line = reader.readLine()) != null) {
line = line.trim();
if (line.startsWith(";") || line.isEmpty()) continue;
if (line.startsWith("[") && line.endsWith("]")) {
currentSection = line.substring(1, line.length() - 1).trim();
} else if (line.contains("=")) {
String[] parts = line.split("=", 2);
String key = parts[0].trim();
String value = parts.length > 1 ? parts[1].trim() : "";
String fullKey = currentSection.isEmpty() ? key : currentSection + "." + key;
properties.put(fullKey, value);
}
}
}
printProperties();
}
public void printProperties() {
System.out.println("Properties:");
for (Map.Entry<String, String> entry : properties.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
}
public void write(Map<String, String> newProperties) throws IOException {
properties.putAll(newProperties);
Map<String, Map<String, String>> sections = new LinkedHashMap<>();
for (Map.Entry<String, String> entry : properties.entrySet()) {
String fullKey = entry.getKey();
String value = entry.getValue();
String section = "";
String key = fullKey;
if (fullKey.contains(".")) {
String[] parts = fullKey.split("\\.", 2);
section = parts[0];
key = parts[1];
}
sections.computeIfAbsent(section, k -> new LinkedHashMap<>()).put(key, value);
}
try (BufferedWriter writer = new BufferedWriter(new FileWriter(filepath))) {
for (Map.Entry<String, Map<String, String>> secEntry : sections.entrySet()) {
if (!secEntry.getKey().isEmpty()) {
writer.write("[" + secEntry.getKey() + "]\n");
}
for (Map.Entry<String, String> prop : secEntry.getValue().entrySet()) {
writer.write(prop.getKey() + " = " + prop.getValue() + "\n");
}
}
}
}
// Example usage:
// public static void main(String[] args) throws IOException {
// IFBHandler handler = new IFBHandler("example.ifb");
// handler.read();
// Map<String, String> updates = new HashMap<>();
// updates.put("Siebel Interface Manager.PROCESS", "NewValue");
// handler.write(updates);
// }
}
- JavaScript class for .IFB file handling:
class IFBHandler {
constructor(filepath) {
this.filepath = filepath;
this.properties = {};
}
async read() {
// Note: In Node.js, use fs module
const fs = require('fs');
let content = fs.readFileSync(this.filepath, 'utf8');
// Handle line continuations
content = content.replace(/\\\n/g, '');
const lines = content.split('\n');
let currentSection = '';
lines.forEach(line => {
line = line.trim();
if (line.startsWith(';') || line === '') return;
if (line.startsWith('[') && line.endsWith(']')) {
currentSection = line.slice(1, -1).trim();
} else if (line.includes('=')) {
let [key, value] = line.split('=', 2).map(s => s.trim());
const fullKey = currentSection ? `${currentSection}.${key}` : key;
this.properties[fullKey] = value;
}
});
this.printProperties();
}
printProperties() {
console.log('Properties:');
for (const [key, value] of Object.entries(this.properties)) {
console.log(`${key}: ${value}`);
}
}
write(newProperties) {
Object.assign(this.properties, newProperties);
const sections = {};
for (const [fullKey, value] of Object.entries(this.properties)) {
let section = '';
let key = fullKey;
if (fullKey.includes('.')) {
[section, key] = fullKey.split('.', 2);
}
if (!sections[section]) sections[section] = {};
sections[section][key] = value;
}
let content = '';
for (const [section, props] of Object.entries(sections)) {
if (section) content += `[${section}]\n`;
for (const [key, value] of Object.entries(props)) {
content += `${key} = ${value}\n`;
}
}
const fs = require('fs');
fs.writeFileSync(this.filepath, content, 'utf8');
}
}
// Example usage:
// const handler = new IFBHandler('example.ifb');
// await handler.read();
// handler.write({'Siebel Interface Manager.PROCESS': 'NewValue'});
- C class (using C++ for class support) for .IFB file handling:
#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <sstream>
class IFBHandler {
private:
std::string filepath;
std::map<std::string, std::string> properties;
public:
IFBHandler(const std::string& fp) : filepath(fp) {}
void read() {
properties.clear();
std::ifstream file(filepath);
if (!file) {
std::cerr << "Error opening file." << std::endl;
return;
}
std::string line, currentSection;
while (std::getline(file, line)) {
// Handle line continuation
while (line.back() == '\\') {
line.pop_back();
std::string nextLine;
std::getline(file, nextLine);
line += nextLine;
}
std::istringstream iss(line);
std::string trimmed;
std::getline(iss >> std::ws, trimmed, '\n');
if (trimmed.empty() || trimmed[0] == ';') continue;
if (trimmed[0] == '[' && trimmed.back() == ']') {
currentSection = trimmed.substr(1, trimmed.size() - 2);
} else {
size_t eqPos = trimmed.find('=');
if (eqPos != std::string::npos) {
std::string key = trimmed.substr(0, eqPos);
std::string value = trimmed.substr(eqPos + 1);
// Trim spaces
key.erase(0, key.find_first_not_of(" \t"));
key.erase(key.find_last_not_of(" \t") + 1);
value.erase(0, value.find_first_not_of(" \t"));
value.erase(value.find_last_not_of(" \t") + 1);
std::string fullKey = currentSection.empty() ? key : currentSection + "." + key;
properties[fullKey] = value;
}
}
}
printProperties();
}
void printProperties() {
std::cout << "Properties:" << std::endl;
for (const auto& pair : properties) {
std::cout << pair.first << ": " << pair.second << std::endl;
}
}
void write(const std::map<std::string, std::string>& newProperties) {
for (const auto& pair : newProperties) {
properties[pair.first] = pair.second;
}
std::map<std::string, std::map<std::string, std::string>> sections;
for (const auto& pair : properties) {
std::string fullKey = pair.first;
std::string value = pair.second;
std::string section, key;
size_t dotPos = fullKey.find('.');
if (dotPos != std::string::npos) {
section = fullKey.substr(0, dotPos);
key = fullKey.substr(dotPos + 1);
} else {
key = fullKey;
}
sections[section][key] = value;
}
std::ofstream file(filepath);
if (!file) {
std::cerr << "Error writing file." << std::endl;
return;
}
for (const auto& secPair : sections) {
if (!secPair.first.empty()) {
file << "[" << secPair.first << "]" << std::endl;
}
for (const auto& propPair : secPair.second) {
file << propPair.first << " = " << propPair.second << std::endl;
}
}
}
};
// Example usage:
// int main() {
// IFBHandler handler("example.ifb");
// handler.read();
// std::map<std::string, std::string> updates = {{"Siebel Interface Manager.PROCESS", "NewValue"}};
// handler.write(updates);
// return 0;
// }