jaromail

a commandline tool to easily and privately handle your e-mail
git clone git://parazyd.org/jaromail.git
Log | Files | Refs | Submodules | README

commit cb2002f7d05b97aea2cd0da71b3fb1e0a64c8bc7
parent 0ec34d7154d42a04d115ae3bf1429857a69252a3
Author: Jaromil <jaromil@dyne.org>
Date:   Mon, 19 Mar 2012 22:33:15 +0100

Mail to Mutt imported for Apple/OSX

Diffstat:
Aaux/MailToMutt/Info.plist | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Aaux/MailToMutt/MailToMutt.entitlements | 8++++++++
Aaux/MailToMutt/MailToMutt.xcodeproj/project.pbxproj | 294+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aaux/MailToMutt/MailToMutt.xcodeproj/project.xcworkspace/contents.xcworkspacedata | 7+++++++
Aaux/MailToMutt/MailToMutt.xcodeproj/project.xcworkspace/xcuserdata/jaromil.xcuserdatad/UserInterfaceState.xcuserstate | 0
Aaux/MailToMutt/MailToMutt.xcodeproj/xcuserdata/jaromil.xcuserdatad/xcschemes/MailToMutt.xcscheme | 85+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aaux/MailToMutt/MailToMutt.xcodeproj/xcuserdata/jaromil.xcuserdatad/xcschemes/xcschememanagement.plist | 22++++++++++++++++++++++
Aaux/MailToMutt/MailtoMutt_Prefix.pch | 15+++++++++++++++
Aaux/MailToMutt/Mutt.h | 21+++++++++++++++++++++
Aaux/MailToMutt/Mutt.m | 121+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aaux/MailToMutt/NSStringExt.h | 9+++++++++
Aaux/MailToMutt/NSStringExt.m | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aaux/MailToMutt/URLHandler.h | 6++++++
Aaux/MailToMutt/URLHandler.m | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aaux/MailToMutt/main.m | 8++++++++
15 files changed, 769 insertions(+), 0 deletions(-)

diff --git a/aux/MailToMutt/Info.plist b/aux/MailToMutt/Info.plist @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>English</string> + <key>CFBundleDocumentTypes</key> + <array> + <dict> + <key>CFBundleTypeExtensions</key> + <array> + <string>inetloc</string> + </array> + <key>CFBundleTypeName</key> + <string>URL</string> + <key>CFBundleTypeRole</key> + <string>None</string> + </dict> + </array> + <key>CFBundleExecutable</key> + <string>MailtoMutt</string> + <key>CFBundleIconFile</key> + <string>MailtoMutt</string> + <key>CFBundleIdentifier</key> + <string>net.sourceforge.MailtoMutt</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>MailtoMutt</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleSignature</key> + <string>Mtµt</string> + <key>CFBundleURLTypes</key> + <array> + <dict> + <key>CFBundleURLName</key> + <string>eMail Addressk</string> + <key>CFBundleURLSchemes</key> + <array> + <string>mailto</string> + </array> + </dict> + </array> + <key>CFBundleVersion</key> + <string>0.4.1</string> + <key>NSMainNibFile</key> + <string>MainMenu</string> + <key>NSPrincipalClass</key> + <string>NSApplication</string> +</dict> +</plist> diff --git a/aux/MailToMutt/MailToMutt.entitlements b/aux/MailToMutt/MailToMutt.entitlements @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>com.apple.security.app-sandbox</key> + <true/> +</dict> +</plist> diff --git a/aux/MailToMutt/MailToMutt.xcodeproj/project.pbxproj b/aux/MailToMutt/MailToMutt.xcodeproj/project.pbxproj @@ -0,0 +1,294 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 581236881517D0E50066FA46 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 581236871517D0E50066FA46 /* Cocoa.framework */; }; + 581236921517D0E50066FA46 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 581236901517D0E50066FA46 /* InfoPlist.strings */; }; + 581236941517D0E50066FA46 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 581236931517D0E50066FA46 /* main.m */; }; + 581236981517D0E50066FA46 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 581236961517D0E50066FA46 /* Credits.rtf */; }; + 5812369B1517D0E50066FA46 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5812369A1517D0E50066FA46 /* AppDelegate.m */; }; + 5812369E1517D0E60066FA46 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5812369C1517D0E60066FA46 /* MainMenu.xib */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 581236831517D0E50066FA46 /* MailToMutt.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MailToMutt.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 581236871517D0E50066FA46 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; + 5812368A1517D0E50066FA46 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; + 5812368B1517D0E50066FA46 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; + 5812368C1517D0E50066FA46 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 5812368F1517D0E50066FA46 /* MailToMutt-Info.plist */ = {isa = PBXFileReference; path = "MailToMutt-Info.plist"; sourceTree = "<group>"; }; + 581236911517D0E50066FA46 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; }; + 581236931517D0E50066FA46 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; }; + 581236951517D0E50066FA46 /* MailToMutt-Prefix.pch */ = {isa = PBXFileReference; path = "MailToMutt-Prefix.pch"; sourceTree = "<group>"; }; + 581236971517D0E50066FA46 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = en.lproj/Credits.rtf; sourceTree = "<group>"; }; + 581236991517D0E50066FA46 /* AppDelegate.h */ = {isa = PBXFileReference; path = AppDelegate.h; sourceTree = "<group>"; }; + 5812369A1517D0E50066FA46 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; }; + 5812369D1517D0E60066FA46 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainMenu.xib; sourceTree = "<group>"; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 581236801517D0E50066FA46 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 581236881517D0E50066FA46 /* Cocoa.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 581236781517D0E50066FA46 = { + isa = PBXGroup; + children = ( + 5812368D1517D0E50066FA46 /* MailToMutt */, + 581236861517D0E50066FA46 /* Frameworks */, + 581236841517D0E50066FA46 /* Products */, + ); + sourceTree = "<group>"; + }; + 581236841517D0E50066FA46 /* Products */ = { + isa = PBXGroup; + children = ( + 581236831517D0E50066FA46 /* MailToMutt.app */, + ); + name = Products; + sourceTree = "<group>"; + }; + 581236861517D0E50066FA46 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 581236871517D0E50066FA46 /* Cocoa.framework */, + 581236891517D0E50066FA46 /* Other Frameworks */, + ); + name = Frameworks; + sourceTree = "<group>"; + }; + 581236891517D0E50066FA46 /* Other Frameworks */ = { + isa = PBXGroup; + children = ( + 5812368A1517D0E50066FA46 /* AppKit.framework */, + 5812368B1517D0E50066FA46 /* CoreData.framework */, + 5812368C1517D0E50066FA46 /* Foundation.framework */, + ); + name = "Other Frameworks"; + sourceTree = "<group>"; + }; + 5812368D1517D0E50066FA46 /* MailToMutt */ = { + isa = PBXGroup; + children = ( + 581236991517D0E50066FA46 /* AppDelegate.h */, + 5812369A1517D0E50066FA46 /* AppDelegate.m */, + 5812369C1517D0E60066FA46 /* MainMenu.xib */, + 5812368E1517D0E50066FA46 /* Supporting Files */, + ); + path = MailToMutt; + sourceTree = "<group>"; + }; + 5812368E1517D0E50066FA46 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 5812368F1517D0E50066FA46 /* MailToMutt-Info.plist */, + 581236901517D0E50066FA46 /* InfoPlist.strings */, + 581236931517D0E50066FA46 /* main.m */, + 581236951517D0E50066FA46 /* MailToMutt-Prefix.pch */, + 581236961517D0E50066FA46 /* Credits.rtf */, + ); + name = "Supporting Files"; + sourceTree = "<group>"; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 581236821517D0E50066FA46 /* MailToMutt */ = { + isa = PBXNativeTarget; + buildConfigurationList = 581236A11517D0E60066FA46 /* Build configuration list for PBXNativeTarget "MailToMutt" */; + buildPhases = ( + 5812367F1517D0E50066FA46 /* Sources */, + 581236801517D0E50066FA46 /* Frameworks */, + 581236811517D0E50066FA46 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = MailToMutt; + productName = MailToMutt; + productReference = 581236831517D0E50066FA46 /* MailToMutt.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 5812367A1517D0E50066FA46 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0430; + ORGANIZATIONNAME = Dyne.org; + }; + buildConfigurationList = 5812367D1517D0E50066FA46 /* Build configuration list for PBXProject "MailToMutt" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 581236781517D0E50066FA46; + productRefGroup = 581236841517D0E50066FA46 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 581236821517D0E50066FA46 /* MailToMutt */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 581236811517D0E50066FA46 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 581236921517D0E50066FA46 /* InfoPlist.strings in Resources */, + 581236981517D0E50066FA46 /* Credits.rtf in Resources */, + 5812369E1517D0E60066FA46 /* MainMenu.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 5812367F1517D0E50066FA46 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 581236941517D0E50066FA46 /* main.m in Sources */, + 5812369B1517D0E50066FA46 /* AppDelegate.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 581236901517D0E50066FA46 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 581236911517D0E50066FA46 /* en */, + ); + name = InfoPlist.strings; + sourceTree = "<group>"; + }; + 581236961517D0E50066FA46 /* Credits.rtf */ = { + isa = PBXVariantGroup; + children = ( + 581236971517D0E50066FA46 /* en */, + ); + name = Credits.rtf; + sourceTree = "<group>"; + }; + 5812369C1517D0E60066FA46 /* MainMenu.xib */ = { + isa = PBXVariantGroup; + children = ( + 5812369D1517D0E60066FA46 /* en */, + ); + name = MainMenu.xib; + sourceTree = "<group>"; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 5812369F1517D0E60066FA46 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + COPY_PHASE_STRIP = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.7; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + }; + name = Debug; + }; + 581236A01517D0E60066FA46 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.7; + SDKROOT = macosx; + }; + name = Release; + }; + 581236A21517D0E60066FA46 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "MailToMutt/MailToMutt-Prefix.pch"; + INFOPLIST_FILE = "MailToMutt/MailToMutt-Info.plist"; + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = app; + }; + name = Debug; + }; + 581236A31517D0E60066FA46 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "MailToMutt/MailToMutt-Prefix.pch"; + INFOPLIST_FILE = "MailToMutt/MailToMutt-Info.plist"; + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = app; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 5812367D1517D0E50066FA46 /* Build configuration list for PBXProject "MailToMutt" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5812369F1517D0E60066FA46 /* Debug */, + 581236A01517D0E60066FA46 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 581236A11517D0E60066FA46 /* Build configuration list for PBXNativeTarget "MailToMutt" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 581236A21517D0E60066FA46 /* Debug */, + 581236A31517D0E60066FA46 /* Release */, + ); + defaultConfigurationIsVisible = 0; + }; +/* End XCConfigurationList section */ + }; + rootObject = 5812367A1517D0E50066FA46 /* Project object */; +} diff --git a/aux/MailToMutt/MailToMutt.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/aux/MailToMutt/MailToMutt.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Workspace + version = "1.0"> + <FileRef + location = "self:MailToMutt.xcodeproj"> + </FileRef> +</Workspace> diff --git a/aux/MailToMutt/MailToMutt.xcodeproj/project.xcworkspace/xcuserdata/jaromil.xcuserdatad/UserInterfaceState.xcuserstate b/aux/MailToMutt/MailToMutt.xcodeproj/project.xcworkspace/xcuserdata/jaromil.xcuserdatad/UserInterfaceState.xcuserstate Binary files differ. diff --git a/aux/MailToMutt/MailToMutt.xcodeproj/xcuserdata/jaromil.xcuserdatad/xcschemes/MailToMutt.xcscheme b/aux/MailToMutt/MailToMutt.xcodeproj/xcuserdata/jaromil.xcuserdatad/xcschemes/MailToMutt.xcscheme @@ -0,0 +1,85 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Scheme + version = "1.3"> + <BuildAction + parallelizeBuildables = "YES" + buildImplicitDependencies = "YES"> + <BuildActionEntries> + <BuildActionEntry + buildForTesting = "YES" + buildForRunning = "YES" + buildForProfiling = "YES" + buildForArchiving = "YES" + buildForAnalyzing = "YES"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "581236821517D0E50066FA46" + BuildableName = "MailToMutt.app" + BlueprintName = "MailToMutt" + ReferencedContainer = "container:MailToMutt.xcodeproj"> + </BuildableReference> + </BuildActionEntry> + </BuildActionEntries> + </BuildAction> + <TestAction + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + shouldUseLaunchSchemeArgsEnv = "YES" + buildConfiguration = "Debug"> + <Testables> + </Testables> + <MacroExpansion> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "581236821517D0E50066FA46" + BuildableName = "MailToMutt.app" + BlueprintName = "MailToMutt" + ReferencedContainer = "container:MailToMutt.xcodeproj"> + </BuildableReference> + </MacroExpansion> + </TestAction> + <LaunchAction + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + launchStyle = "0" + useCustomWorkingDirectory = "NO" + buildConfiguration = "Debug" + ignoresPersistentStateOnLaunch = "NO" + debugDocumentVersioning = "YES" + allowLocationSimulation = "YES"> + <BuildableProductRunnable> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "581236821517D0E50066FA46" + BuildableName = "MailToMutt.app" + BlueprintName = "MailToMutt" + ReferencedContainer = "container:MailToMutt.xcodeproj"> + </BuildableReference> + </BuildableProductRunnable> + <AdditionalOptions> + </AdditionalOptions> + </LaunchAction> + <ProfileAction + shouldUseLaunchSchemeArgsEnv = "YES" + savedToolIdentifier = "" + useCustomWorkingDirectory = "NO" + buildConfiguration = "Release" + debugDocumentVersioning = "YES"> + <BuildableProductRunnable> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "581236821517D0E50066FA46" + BuildableName = "MailToMutt.app" + BlueprintName = "MailToMutt" + ReferencedContainer = "container:MailToMutt.xcodeproj"> + </BuildableReference> + </BuildableProductRunnable> + </ProfileAction> + <AnalyzeAction + buildConfiguration = "Debug"> + </AnalyzeAction> + <ArchiveAction + buildConfiguration = "Release" + revealArchiveInOrganizer = "YES"> + </ArchiveAction> +</Scheme> diff --git a/aux/MailToMutt/MailToMutt.xcodeproj/xcuserdata/jaromil.xcuserdatad/xcschemes/xcschememanagement.plist b/aux/MailToMutt/MailToMutt.xcodeproj/xcuserdata/jaromil.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>SchemeUserState</key> + <dict> + <key>MailToMutt.xcscheme</key> + <dict> + <key>orderHint</key> + <integer>0</integer> + </dict> + </dict> + <key>SuppressBuildableAutocreation</key> + <dict> + <key>581236821517D0E50066FA46</key> + <dict> + <key>primary</key> + <true/> + </dict> + </dict> +</dict> +</plist> diff --git a/aux/MailToMutt/MailtoMutt_Prefix.pch b/aux/MailToMutt/MailtoMutt_Prefix.pch @@ -0,0 +1,15 @@ +// +// Prefix header for all source files of the 'MailtoMutt' target in the 'MailtoMutt' project +// + +#ifdef __OBJC__ + #import <Cocoa/Cocoa.h> +#endif + + +#ifdef VERBOSE_DEBUG_OUTPUT + #warning Debugging output enabled + #define NSDebug(x, ...) NSLog([ NSString stringWithFormat:@"%s: %@", __PRETTY_FUNCTION__, x], ## __VA_ARGS__ ) +#else + #define NSDebug(x, ...) /* x, ## __VA_ARGS__ */ +#endif diff --git a/aux/MailToMutt/Mutt.h b/aux/MailToMutt/Mutt.h @@ -0,0 +1,20 @@ +/* High-level abstraction of the mutt mailer + * Implemented using AppleScripts and Terminal.app */ + + +#import <Foundation/Foundation.h> + +@interface Mutt : NSObject +/* Currently we cannot abstract the instance of the object into an instance of mutt. + * Hence all the methods are class methods, which return no value, and start a new mutt in a new terminal window */ ++ (void)newMessageWithContent:(NSString *)content; // create a message from a string, should be RFC822 ++ (void)newMessageFromFile:(NSString *)file; // create a message from a file, should be RFC822 ++ (void)newMessageTo:(NSString *)to withSubject:(NSString *)subject andBody:(NSString *)body; // create a message with a subject, a recipient and a body as strings ++ (void)newMessageTo:(NSString *)to withSubject:(NSString *)subject; // various permutions.. blech. ++ (void)newMessageTo:(NSString *)to withBody:(NSString *)body; ++ (void)newMessageTo:(NSString *)to; ++ (void)newMessageWithSubject:(NSString *)subject andBody:(NSString *)body; ++ (void)newMessageWithSubject:(NSString *)subject; ++ (void)newMessageWithBody:(NSString *)body; ++ (void)newMessage; // create an empty message +@end+ \ No newline at end of file diff --git a/aux/MailToMutt/Mutt.m b/aux/MailToMutt/Mutt.m @@ -0,0 +1,121 @@ +#import "NSStringExt.h" +#import "Mutt.h" + +#include <string.h> +#include <unistd.h> + +@implementation Mutt + +/* opens mutt with a file */ + ++ (void) newMessageFromFile:(NSString *)path +{ + NSDebug(@"Opening mutt with file %@", path); + + /* create the source to the script */ + NSString *source = [ NSString stringWithFormat:@"tell application \"Terminal\"\nactivate\ndo script \"mutt -H '%@' \"\nend tell", path ]; + + /* create the NSAppleScript object with the source */ +# warning NSAppleScript has a leak when initializing objects + NSAppleScript *script = [ [ [ NSAppleScript alloc ] initWithSource:source ] autorelease ]; + + NSDebug(@"The compiled script is \n<<EOF\n%@\nEOF", [ script source ]); + + /* create a dictionary in which the execution will store it's errors */ + NSMutableDictionary *dict = [ NSMutableDictionary dictionary ]; + + /* execute */ + if ([ script executeAndReturnError:&dict ]){ + NSDebug(@"Script executed OK"); + } else { + NSDebug(@"Couldn't execute script:\n%@", dict); + } +} + +/* makes a temp file */ + ++ (void) newMessageWithContent:(NSString *)content +{ + NSDebug(@"creating message with content\n<<EOF\n%@\nEOF", content); + + /* use the mktemp(3) family of functions (standard C library) to create a temporary file, openned atomically in the users home directory */ + /* mkstemp takes a template - it replaces the XX part at the end with random stuff, and then opens the file safely, that is only if it doesn't exist */ + /* we first build a format, which should be like /tmp/501/Temporary\ Items/MailtoMutt-XXXXXXXX, and then get the cString out of it */ + /* the following code section leaves us with template, a c string which we have to dispose of */ + +# warning UTF8String created - we might prefer ASCII. How do we do it cleanly? NSString has got a notion of a default encoding (user preferences setting), which affects the cString methods + NSDebug(@"Preparing UTF8 string"); + const char *constTemplate = [ [ NSString stringWithFormat:@"%@/MailtoMutt-XXXXXXXX", NSTemporaryDirectory() ] UTF8String ]; /* create the filename. It's constant, so we have to copy it */ + NSDebug(@"Determining length of constTemplate"); + size_t templateLength = (strlen(constTemplate) + 1) * sizeof(char); /* the length of the string, plus the null byte */ + NSDebug(@"created template %s with length %d", constTemplate, templateLength); + + char *template; +# warning malloc fail will not raise exception but simply return + if ((template = (char *)malloc(templateLength)) == NULL){ /* malloc this length */ + NSDebug(@"Malloc failed"); + return; // should raise NSException instead + } + + (void)strlcpy(template, constTemplate, templateLength); /* copy the string to a non const one. beh. */ + NSDebug(@"copied string"); + int fd = mkstemp(template); /* make the template */ + NSDebug(@"mkstmp created <<%s>>", template); + + /* create a filehandle out of the filedescriptor that mkstemp gave us */ + NSFileHandle *fh = [ [ [ NSFileHandle alloc ] initWithFileDescriptor:fd ] autorelease ]; + + + NSDebug(@"Writing message:\n<<EOF\n%@\nEOF", content); + [ fh writeData:[ content dataUsingEncoding:NSUTF8StringEncoding ] ]; /* write the contents into the file */ + [ fh closeFile ]; /* finished writing */ + + + /* use the temp file to create a mutt message */ + [ [ self class ] newMessageFromFile:[ NSString stringWithUTF8String:template ] ]; + + NSDebug(@"deleting temp file"); +# warning zombie files left in temp dir, cant find logical way to clean up + /* unlink(template); don't delete the file - mutt probably hasn't openned it. If we can monitor vnode /access/, maybe this can be solved */ + free(template); /* deallocate the template string */ +} + +/* concatenates content to message */ + ++ (void) newMessageTo:(NSString *)to withSubject:(NSString *)subject andBody:(NSString *)body + { + [ self newMessageWithContent:[ NSString stringWithFormat:@"To: %@\nSubject: %@\n\n%@",[ to headerEscape], [ subject headerEscape ], body ] ]; +} + +/* all 3 pieces */ + ++ (void) newMessageWithSubject:(NSString *)subject andBody:(NSString *)body +{ + [ [ self class ] newMessageTo:@"" withSubject:subject andBody:body ]; +} ++ (void) newMessageTo:(NSString *)to withBody:(NSString *)body +{ + [ [ self class ] newMessageTo:to withSubject:@"" andBody:body ]; +} ++ (void) newMessageTo:(NSString *)to withSubject:(NSString *)subject +{ + [ [ self class ] newMessageTo:to withSubject:subject andBody:@"" ]; +} +/* very cheap */ ++ (void) newMessageWithBody:(NSString *)body + { + [ [ self class ] newMessageTo:@"" withBody:body ]; +} ++ (void) newMessageTo:(NSString *)to +{ + [ [ self class ] newMessageTo:to withSubject:@"" ]; +} ++ (void) newMessageWithSubject:(NSString *)subject +{ + [ [ self class ] newMessageTo:@"" withSubject:subject ]; +} ++ (void) newMessage +{ + [ [ self class ] newMessageTo:@"" ]; +} +@end diff --git a/aux/MailToMutt/NSStringExt.h b/aux/MailToMutt/NSStringExt.h @@ -0,0 +1,8 @@ +/* Extensions to the NSString class */ + +#import "Foundation/Foundation.h" + +@interface NSString (Misc) +- (NSString *) headerEscape; // makes a string suitable for inserting into an RFC822 header +- (NSString *) urlDecode; // decodes strings like "foo+bar%20gorch" into "foo bar gorch" +@end+ \ No newline at end of file diff --git a/aux/MailToMutt/NSStringExt.m b/aux/MailToMutt/NSStringExt.m @@ -0,0 +1,59 @@ +/* adapted from the iJournal project ( http://sf.net/projects/ijournal ) */ + +#import "NSStringExt.h" + + +@implementation NSString (Misc) +- (NSString *) headerEscape +{ + if ([ self length ] > 0){ + NSMutableString *clean = [ self mutableCopy ]; + + /* clean up the string so that it's line breaks are all CRLF, and followed by spaces */ + [ clean replaceOccurrencesOfString:@"\r" withString:@"\n" options:0 range:NSMakeRange(0, [ clean length ]) ]; /* make all CRs be LFs */ + NSArray *lines = [ clean componentsSeparatedByString:@"\n" ]; /* split on LFs */ + [ clean release ]; /* throw away the changed string, we no longer need it */ + + if ([ lines count ] > 0){ + NSEnumerator *cursor = [ lines objectEnumerator ]; /* iterate the array of lines */ + + clean = [ [ [ NSMutableString alloc ] initWithCapacity:([ self length ] + 20) ] autorelease ]; /* better to malloc a bit extra than to malloc many times */ + [ clean appendString:[ cursor nextObject ] ]; /* add the first part now, we don't want it with a CRLF before it */ + + NSString *line; + while(line = [ cursor nextObject ]){ + if ([ line length ] > 0){ /* some lines might be empty, we don't want them */ + [ clean appendString:@"\015\012 " ]; /* RFC822 header continuations are CRLF, then whitespace */ + [ clean appendString:line ]; + } else { + NSDebug(@"Empty line"); + } + } + + return clean; + } + } + + NSDebug(@"Empty string escaped for header"); + + return @""; +} +- (NSString *) urlDecode +{ + NSString *decoded; + NSMutableString *decodedSpaces; + + // first convert the +'s back into whitespaces + decodedSpaces = [NSMutableString stringWithString:self]; + [decodedSpaces replaceOccurrencesOfString:@"+" + withString:@" " + options:0 + range:NSMakeRange(0, [self length])]; + + // then convert all the %-escaped sequences back into chars + decoded = (NSString *)CFURLCreateStringByReplacingPercentEscapes(NULL,(CFStringRef)decodedSpaces, (CFStringRef)@""); /* NSString has stringByReplacingPercentEscapesUsingEncding - i don't know which encoding. UTF8 is probably a safe bet */ + [ decoded autorelease ]; // if i got the docs right, CFUrlCreateString.... returns an object with a reference count of 1, as if i did alloc on my own + + return decoded; +} +@end diff --git a/aux/MailToMutt/URLHandler.h b/aux/MailToMutt/URLHandler.h @@ -0,0 +1,6 @@ +#import <Foundation/Foundation.h> + +@interface URLHandler : NSObject +- (void)awakeFromNib; // initial action, registers apple event +- (void)getUrl:(NSAppleEventDescriptor *)event; // handles the GetURL event +@end diff --git a/aux/MailToMutt/URLHandler.m b/aux/MailToMutt/URLHandler.m @@ -0,0 +1,62 @@ +#import <Cocoa/Cocoa.h> + +#import "URLHandler.h" +#import "NSStringExt.h" +#import "Mutt.h" + +@implementation URLHandler +- (void)awakeFromNib +{ /* this is from ed2k Helper, it registers that we want the getUrl method to handle kAEGetURL - an appleevent. It's all magic to me. */ + [[ NSAppleEventManager sharedAppleEventManager ] + setEventHandler: self + andSelector: @selector(getUrl:) + forEventClass: kInternetEventClass + andEventID: kAEGetURL ]; + NSDebug(@"Registered for apple event"); +} +- (void)getUrl:(NSAppleEventDescriptor *)event +{ + NSString *urlString = [[event paramDescriptorForKeyword:'----'] stringValue ]; + NSDebug(@"GetURL apple event received with <<%@>>", urlString); + NSURL *url = [ NSURL URLWithString:urlString ]; // get the URL delivered by the apple event + + if (url == nil){ // if NSURL did not eat it, then we give up + NSDebug(@"couldn't parse URL"); + return; + } + NSDebug(@"URL successfully parsed"); + + NSArray *parts = [[url resourceSpecifier] componentsSeparatedByString:@"?" ]; // get an address, and a query string + + NSString *email = [ [ parts objectAtIndex:0 ] urlDecode ]; // this is the email part of the URL + + NSMutableDictionary *paramDict = [ NSMutableDictionary dictionaryWithObjectsAndKeys:@"",@"subject",@"",@"body",nil ]; + + if ([ parts count ] > 1){ + NSDebug(@"there are %d parts of the URL to check, %@.", [ parts count ], ([ parts count ] > 2 ? @"but there should only be 1 or 2" : @"which is good")); + NSArray *params = [ [ parts objectAtIndex:1 ] componentsSeparatedByString:@"&" ]; // split into param=value pairs + NSDebug(@"There are %d parameters (key=value) in the second part of the URL (the query string)", [ params count ]); + NSEnumerator *cursor = [ params objectEnumerator ]; + + id string; // points to an object, a param=value pair in this case, by walking params + + /* very cheap query param "parsing" */ + while(string = [ cursor nextObject ]){ + NSArray *kvp = [ string componentsSeparatedByString:@"=" ]; // seperate into key and value + if ([ kvp count ] != 2){ + NSDebug(@"KVP count is %d!=2. Doesn't look like a valid query string part.", [ kvp count] ); + continue; + } + NSString *key = [ kvp objectAtIndex:0 ]; // this shuts up the warnings - i still don't know how to cast an object like [ (NSString *)[ kvp objectAtIndex: 0 ] compare:@"subject" ] + NSDebug(@"param %@ found in URL, with value %@", key, [[ kvp objectAtIndex:1 ] urlDecode ]); + if (![ key compare:@"subject" ] || ![ key compare:@"body" ]) // these are what we want + [ paramDict setValue:[[ kvp objectAtIndex:1 ] urlDecode ] forKey:key ]; // urlDecode was stolen from iJournal + } + } + + NSDebug(@"Going to mail '%@' with subject '%@' and body:\n<<EOF\n%@\nEOF", email, [ paramDict valueForKey:@"subject" ], [ paramDict valueForKey:@"body" ]); + + /* create the message using ultraleet abstraction of Mutt ;-) */ + [ Mutt newMessageTo:email withSubject:[ paramDict valueForKey:@"subject" ] andBody:[ paramDict valueForKey:@"body" ] ]; +} +@end diff --git a/aux/MailToMutt/main.m b/aux/MailToMutt/main.m @@ -0,0 +1,8 @@ + +#import <Cocoa/Cocoa.h> + +int main(int argc, const char *argv[]) +{ + return NSApplicationMain(argc, argv); +} +