iOS/Objective-C: library to connect to POP3 - objective-c

I'd like to connect to IMAP and POP3 servers, for IMAP I'm currently using MailCore. Unfortunately I don't find a suitable POP3-framwork.
I tried with libetpan:
mailpop3 * pop3;
int r;
pop3 = mailpop3_new(0, NULL);
r = mailpop3_ssl_connect(pop3, "pop.gmail.com", 995);
check_error(r, "connect failed");
but I always get a connection refused error; and it's only C, I would prefer Objective-C. Even better would be a library which I could use for both; IMAP and POP3.

I haven't used OCMail, but it seems like it's what you're looking for. It claims to support "POP3, IMAP4, SMTP, POPS, IMAPS, SMTPS".
Edit: Build Error
Turns out, the solution is actually in the README file.
Once you've downloaded the ZIP from Github, open the Xcode project.
Build for Profiling (Product Menu > Build For > Profiling (Command-Shift-I)).
Open Xcode preferences and go to "Locations"
Under Derived Data, next to the Advanced button you'll see a file path (something like /Users/YourUserName/Library/Developer/Xcode/DerivedData). There'll be a little arrow next to the path; click the arrow to go to that location in Finder.
It'll take you to a folder with all of your Xcode projects. Find the folder whose name starts with OCMail (and has a bunch of gibberish after it).
In that folder, find Build > Products > Debug-iphoneos > libOCMail.a. That's the library file you'll want to add into your Xcode project. Just drag it into your Xcode project and you should be good to go.
I got a bunch of errors building the project. They came from a badly defined enum type. Here's a cleaned up file:
http://cl.ly/code/442x2x3X3Y2I
Just download and replace the existing MimeMessage.m file before you build.

I was working with libetpan in past and I was connecting to pop3 server without problems, so I checked if it still working. I used code from here: https://github.com/dinhviethoa/libetpan/blob/master/tests/pop-sample.c and adjusted it for iOS.
If You use it, You will see a lot of warnings and app will crash after fetching first message, but connecting is working (of course, You need to enter Your email login and password).
I'm not saying that libetpan is good solution. When I was developing app with mail support I also used mailcore for IMAP and eventually resigned from POP3 support. But if You run from options it could be useful.
static void check_error(int r, char * msg)
{
if (r == MAILPOP3_NO_ERROR)
return;
fprintf(stderr, "%s\n", msg);
exit(EXIT_FAILURE);
}
-(IBAction)testButtonClick:(id)sender
{
mailpop3 * pop3;
int r;
carray * list;
unsigned int i;
// if (argc < 3) {
// fprintf(stderr, "syntax: pop-sample [gmail-email-address] [gmail- password]\n");
// exit(EXIT_FAILURE);
// }
mkdir("download", 0700);
pop3 = mailpop3_new(0, NULL);
r = mailpop3_ssl_connect(pop3, "pop.gmail.com", 995);
check_error(r, "connect failed");
r = mailpop3_user(pop3, #"mail login".cString);
check_error(r, "user failed");
r = mailpop3_pass(pop3, #"mail password".cString);
check_error(r, "pass failed");
r = mailpop3_list(pop3, &list);
check_error(r, "list failed");
NSLog(#"carray_count(list_: %d", carray_count(list));
for(i = 0 ; i < carray_count(list) ; i ++) {
struct mailpop3_msg_info * info;
char * msg_content;
size_t msg_size;
FILE * f;
char filename[512];
struct stat stat_info;
info = (mailpop3_msg_info *) carray_get(list, i);
if (info->msg_uidl == NULL) {
continue;
}
snprintf(filename, sizeof(filename), "download/%s.eml", info->msg_uidl);
r = stat(filename, &stat_info);
if (r == 0) {
printf("already fetched %u %s\n", info->msg_index, info->msg_uidl);
continue;
}
if(msg_content != NULL)
NSLog(#"msg_content: %#", [NSString stringWithUTF8String:msg_content]);
r = mailpop3_retr(pop3, info->msg_index, &msg_content, &msg_size);
check_error(r, "get failed");
// f = fopen(filename, "w");
// fwrite(msg_content, 1, msg_size, f);
// fclose(f);
// mailpop3_retr_free(msg_content);
if (info->msg_uidl != NULL) {
printf("fetched %u %s\n", info->msg_index, info->msg_uidl);
}
else {
printf("fetched %u\n", info->msg_index);
}
}
mailpop3_quit(pop3);
mailpop3_free(pop3);
// exit(EXIT_SUCCESS);
}

Related

Linux-Xenomai Serial Communication using xeno_16550A module

I'm starter of RTOS and I'm using Xenomai v2.6.3.
I'm trying to get some data using Serial communication.
I did my best on the task following the xenomai's guide and open sources, but it doesn't work well.
the link of the guide --> (https://xenomai.org//serial-16550a-driver/)
I just followed the sequence to use the module xeno_16550A. (with port io = 0x2f8 and irq=3)
I followed open source http://www.acadis.org/pages/captain.at/serial-port-example
It works well in write task, but read task doesn't work well.
It gave me the error sentence with error while RTSER_RTIOC_WAIT_EVENT, code -110 (it means connection timed out)
Moreover I checked the irq number3 by typing command 'cat /proc/xenomai/irq', but the interrupt number doesn't increase.
In my case, I don't need to write data, so I erase the write task code.
The read task proc is follow
void read_task_proc(void *arg) {
int ret;
ssize_t red = 0;
struct rtser_event rx_event;
while (1) {
/* waiting for event */
ret = rt_dev_ioctl(my_fd, RTSER_RTIOC_WAIT_EVENT, &rx_event );
if (ret) {
printf(RTASK_PREFIX "error while RTSER_RTIOC_WAIT_EVENT, code %d\n",ret);
if (ret == -ETIMEDOUT)
continue;
break;
}
unsigned char buf[1];
red = rt_dev_read(my_fd, &buf, 1);
if (red < 0 ) {
printf(RTASK_PREFIX "error while rt_dev_read, code %d\n",red);
} else {
printf(RTASK_PREFIX "only %d byte received , char : %c\n",red,buf[0]);
}
}
exit_read_task:
if (my_state & STATE_FILE_OPENED) {
if (!close_file( my_fd, READ_FILE " (rtser)")) {
my_state &= ~STATE_FILE_OPENED;
}
}
printf(RTASK_PREFIX "exit\n");
}
I could guess the causes of the problem.
buffer size or buffer is already full when new data is received.
rx_interrupt doesn't work....
I want to check whether the two things are wrong or not, but How can I check?
Furthermore, does anybody know the cause of the problem? Please give me comments.

GStreamer demo deosn't work in Virtual Machine (seeking simple example)

I am tryign to code an extremely simple GStreamer app. It doesn't matter what it does, so long as GStreamer does something. Even just displaying some text or a simple JPEG would be fine.
Below is about the best example that I could find by Googling (I have added a few error checks). When I run it in a Linux Virtual Machine running under Windows, I see this console message:
libEGL warning: pci id for fd 4: 80ee:beef, driver (null)
libEGL warning: DRI2: failed to open vboxvideo (search paths
/usr/lib/i386-linux-gnu/dri:${ORIGIN}/dri:/usr/lib/dri)
Googling indicates that this is an error with 3D rendering inside a virtual machine. I can find no solution.
So, can someone fix the code below so that it will run in a VM? I assume that that would mean avoiding 3D rendering, so maybe display an image or some text? It is not necessary to play video, this is just a simple proof of concept of using GStreamer inside something else (which has to be running in a VM).
Here's the code ...
void GstreamerPlayVideo()
{
GstElement *pipeline;
GstBus *bus;
GstMessage *msg;
int argc;
GError *error = NULL;
/* Initialize GStreamer */
if (gst_init_check(&argc, NULL, &error) == TRUE)
{
/* Build the pipeline */
// Change URL to test failure
pipeline = gst_parse_launch ("bin uri=http://docs.gstreamer.com/media/sintel_trailer-480p.webm", &error);
//// pipeline = gst_parse_launch ("bin uri=http://tecfa.unige.ch/guides/x3d/www.web3d.org/x3d/content/examples/HelloWorld.gif", &error);
if (pipeline != NULL)
{
/* Start playing */
gst_element_set_state (pipeline, GST_STATE_PLAYING);
/* wait until it's up and running or failed */
if (gst_element_get_state (pipeline, NULL, NULL, -1) == GST_STATE_CHANGE_FAILURE)
{
g_error ("GST failed to go into PLAYING state");
exit(1);
}
/* Wait until error or EOS */
bus = gst_element_get_bus (pipeline);
if (bus != NULL)
{
msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_ERROR | GST_MESSAGE_EOS);
/* Parse message */
if (msg != NULL)
{
gchar *debug_info;
switch (GST_MESSAGE_TYPE (msg))
{
case GST_MESSAGE_ERROR:
gst_message_parse_error (msg, &error, &debug_info);
g_printerr ("Error received from element %s: %s\n", GST_OBJECT_NAME (msg->src), error->message);
g_printerr ("Debugging information: %s\n", debug_info ? debug_info : "none");
g_clear_error (&error);
g_free (debug_info);
break;
case GST_MESSAGE_EOS:
g_print ("End-Of-Stream reached.\n");
break;
default:
/* We should not reach here because we only asked for ERRORs and EOS */
g_printerr ("Unexpected message received.\n");
break;
}
gst_message_unref (msg);
}
/* Free resources */
gst_object_unref (bus);
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (pipeline);
}
else
{
g_print ("GST get bus error: %s\n", error->message);
exit(1);
}
}
else
{
g_print ("GST parse error: %s\n", error->message);
exit(1);
}
}
else
{
g_print ("GST init error: %s\n", error->message);
exit(1);
}
} // GstreamerPlayVideo()
Try specifying a video sink by hand in your pipeline.
videotestsrc ! ximagesink
Your system may have an EGL video sink plugin installed as the primary video plugin. ximagesink seems a little more likely to work.
Like this:
//this line is where you're creating your pipeline
pipeline = gst_parse_launch ("videotestsrc ! ximagesink", &error);
I recommend experimenting with the gst-launch command first so you can get a hang of pipeline syntax, what sinks and sources are, etc. The simplest test you can run is something like this (if you have gstreamer 1.0 installed, you may have 0.10), from the command line:
gst-launch-1.0 videotestsrc ! autovideosink

dispatch_source_get_data does not return correct flag when monitoring a directory

Can someone please tell me what is this code not working ? it always return a DISPATH_VNODE_WRITE while monitoring application documents directory in iOS 6.0. (iPad) Below is my code. It returns 0x2 always no matter a file is deleted or renamed or added :(. Is this because it is a directory that I am monitoring ? not a file !!! is there any way I can find out what caused the directory to send notification ?
int directoryFileDescripter = open([documentDirectory UTF8String], O_EVTONLY);
if (directoryFileDescripter < 0) {
NSLog(#"Couldn't obtain file descripter from the system.");
return;
}
dispatch_queue_t mainQueue = /*dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);*/dispatch_get_main_queue();
if (mainQueue == NULL) {
NSLog(#"Couldn't obtain mainQueue from the system.");
close(directoryFileDescripter);
return;
}
dispSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE, directoryFileDescripter, DISPATCH_VNODE_WRITE | DISPATCH_VNODE_DELETE | DISPATCH_VNODE_RENAME, mainQueue);
if (dispSource == NULL) {
NSLog(#"Couldn't obtain dispatch source for directory from the system.");
close(directoryFileDescripter);
return;
}
dispatch_source_set_event_handler(dispSource, ^{
NSLog(#"directory notification received.");
int fileDes = dispatch_source_get_handle(dispSource);
unsigned long mask = dispatch_source_get_data(dispSource);
char path[PATH_MAX] = {0};
int nRes = fcntl(fileDes, F_GETPATH, &path);
if (nRes < 0) {
return;
}
if (mask & DISPATCH_VNODE_WRITE) {
NSLog(#"A file has been written.");
}
if (mask & DISPATCH_VNODE_DELETE) {
NSLog(#"A file has been deleted.");
}
if (mask & DISPATCH_VNODE_RENAME) {
NSLog(#"A file has been renamed.");
}
});
dispatch_source_set_cancel_handler(dispSource, ^{
close(directoryFileDescripter);
});
dispatch_resume(dispSource);
You are correct about the "why." When files are created, renamed, or deleted, the directory is modified. You are watching the directory, so you get a "WRITE" event.
I would typically deal with this by re-scanning the directory each time it is marked as written, and noting the changes yourself. If you're not worried about the directory itself moving or being deleted, you can just watch for WRITE events.
You can of course also watch each file's VNODE, but I expect this would be much more complicated to implement well for this kind of problem.

libusb-1.0 - Where does the data go after a successful libusb_bulk_transfer() call?

I ran the following code sample obtained from a tutorial here: http://www.dreamincode.net/forums/topic/148707-introduction-to-using-libusb-10/
I ran it against a tablet running Android 4 attached via USB to a MacBook Pro running Mac OS X Mountain Lion.
The output contained "Writing Successful!" so I assume libusb_bulk_transfer() worked correctly. My question is where did the 4 bytes of data got transferred to? Can I save it to a file on the Android tablet?
Thanks for your help!
#include <iostream>
#include <libusb.h>
using namespace std;
int main() {
libusb_device **devs; //pointer to pointer of device, used to retrieve a list of devices
libusb_device_handle *dev_handle; //a device handle
libusb_context *ctx = NULL; //a libusb session
int r; //for return values
ssize_t cnt; //holding number of devices in list
r = libusb_init(&ctx); //initialize the library for the session we just declared
if(r < 0) {
cout<<"Init Error "<<r<<endl; //there was an error
return 1;
}
libusb_set_debug(ctx, 3); //set verbosity level to 3, as suggested in the documentation
cnt = libusb_get_device_list(ctx, &devs); //get the list of devices
if(cnt < 0) {
cout<<"Get Device Error"<<endl; //there was an error
return 1;
}
cout<<cnt<<" Devices in list."<<endl;
dev_handle = libusb_open_device_with_vid_pid(ctx, 5118, 7424); //these are vendorID and productID I found for my usb device
if(dev_handle == NULL)
cout<<"Cannot open device"<<endl;
else
cout<<"Device Opened"<<endl;
libusb_free_device_list(devs, 1); //free the list, unref the devices in it
unsigned char *data = new unsigned char[4]; //data to write
data[0]='a';data[1]='b';data[2]='c';data[3]='d'; //some dummy values
int actual; //used to find out how many bytes were written
if(libusb_kernel_driver_active(dev_handle, 0) == 1) { //find out if kernel driver is attached
cout<<"Kernel Driver Active"<<endl;
if(libusb_detach_kernel_driver(dev_handle, 0) == 0) //detach it
cout<<"Kernel Driver Detached!"<<endl;
}
r = libusb_claim_interface(dev_handle, 0); //claim interface 0 (the first) of device (mine had jsut 1)
if(r < 0) {
cout<<"Cannot Claim Interface"<<endl;
return 1;
}
cout<<"Claimed Interface"<<endl;
cout<<"Data->"<<data<<"<-"<<endl; //just to see the data we want to write : abcd
cout<<"Writing Data..."<<endl;
r = libusb_bulk_transfer(dev_handle, (2 | LIBUSB_ENDPOINT_OUT), data, 4, &actual, 0); //my device's out endpoint was 2, found with trial- the device had 2 endpoints: 2 and 129
if(r == 0 && actual == 4) //we wrote the 4 bytes successfully
cout<<"Writing Successful!"<<endl;
else
cout<<"Write Error"<<endl;
r = libusb_release_interface(dev_handle, 0); //release the claimed interface
if(r!=0) {
cout<<"Cannot Release Interface"<<endl;
return 1;
}
cout<<"Released Interface"<<endl;
libusb_close(dev_handle); //close the device we opened
libusb_exit(ctx); //needs to be called to end the
delete[] data; //delete the allocated memory for data
return 0;
}
The libusb_bulk_transfer() function writes the data at the specified endpoint. Its an address, access it, print it, or you can copy it, do some case conversion and dump it to an outgoing endpoint. And, then perform a read through libusb_bulk_transfer()

PepperMount Write operation fails

Am trying to store files in NACL using PepperMount library. But I've some problem in writing files to the persistent storage.
struct stat st;
char data1[1000];
for (int i = 0; i < 1000; i++)
data1[i] = 'a';
if(0 == ppMount->Creat("ccda.txt", 0, &st)) {
fprintf(stderr, "File opened");
ppMount->Ref(st.st_ino);
ssize_t n = ppMount->Write(st.st_ino, 0, data1, 1000);
fprintf(stderr, "Wrote %d bytes", n);
ppMount->Unref(st.st_ino);
} else {
fprintf(stderr, "File open failed");
}
I tried it in Pepper_20 and Pepper_21, in 20 it failes in open file, and in 21 it fails in write operation.
Let me know if this is a known bug or am doing something wrong with my code.
The problem was actually not with the code. Seems like I've to request storage quota from html as well.
window.webkitStorageInfo.requestQuota(PERSISTENT, 20*1024*1024);