How to send an email without using the program RSCONN01? - email

I am trying to send an email with an excel attachment without using rsconn01. If this is possible could you show me how this is done?
I would also like a little bit more information about how rsconn01 works. I am using rsconn01 to send the emails but, I received a complaint that this program was also resending out emails that failed earlier that day.
This is the code I am using now. It works, but I want to know another way to do it without using rsconn01.
`CALL FUNCTION 'SO_DOCUMENT_SEND_API1'
EXPORTING
document_data = w_doc_data
put_in_outbox = 'X'
commit_work = 'X'
IMPORTING
sent_to_all = w_sent_all
TABLES
packing_list = t_packing_list
contents_bin = t_attachment
contents_txt = it_message
receivers = t_receivers
EXCEPTIONS
too_many_receivers = 1
document_not_sent = 2
document_type_not_exist = 3
operation_no_authorization = 4
parameter_error = 5
x_error = 6
enqueue_error = 7
OTHERS = 8.
if sy-subrc = 0.
WAIT UP TO 2 SECONDS.
SUBMIT rsconn01 WITH mode = 'INT'
WITH output = 'X'
AND RETURN.
else.
WRITE:/ 'ERROR IN MAIL ', sy-subrc.
endif.`

You will have to use RSCONN01 unless you'd like to implement your own protocol handling. You're using the standard SAPconnect functionality (although with an API that's a bit outdated, I'd switch to the BCS if I were in your shoes). As long as you're using this, you're stuck with that report. However, you usually won't have to call it for yourself. It's a background process that is called every few minutes to process outgoing mail. Perhaps you're working in a development environment where the SAPconnect system isn't properly setup - in that case, you should talk to your system administrators. There are ways to tune the SAPconnect system to work in many cases. You should try to use the existing and well supported facilities before trying to circumvent them.

Related

OpenDDS Messenger RTPS across 2 virtual machines

I have built OpenDDS-3.20 and I am able to run the Messenger sample code under (OpenDDS-3.20/DevGuideExamples/DCPS/Messenger) by using the run_test.pl. I am also able to run it without the run_test.pl file like this:
OpenDDS-3.20/bin/DCPSInfoRepo &
./publisher &
./subscriber
After this I can see the result:
...
...
...
Subscriber is available
SampleInfo.sample_rank = 0
SampleInfo.instance_state = ALIVE_INSTANCE_STATE
Message: subject = Review
subject_id = 99
from = Comic Book Guy
count = 0
text = Worst. Movie. Ever.
...
...
...
Even with the RTSP, I am able to execute it from the same machine ./run_test.pl --rtps. But, when I am trying to run DCPSInfoRepo and publisher in a VirtualBox-1 and subscriber in VirtualBox-2 using the default rtps.ini file then the sample application does not work.
I am able to ping from VirtualBox-1 to VirtualBox-2. They are both running Ubuntu Server. Can someone please share the process by which RTPS can be used to communicate between publisher and subscriber across 2 virtual machines.

ZMQ socket - disconnect when all request are served

I am trying to implement ZMQ REQ/REP model in Java
I have a Server-role, running on post 5564, which acts as Replier
ZMQ.Socket repSock = context.socket(ZMQ.REP);
I have a Client-role, running on post 5563
ZMQ.Socket syncclient = context.socket(ZMQ.REQ);
I have a proxy-server in middle, which passes request and response
ZMQ.proxy(reqSocket, repSocket, null);
Good thing about having a proxy is I can add multiple Servers
repSocket.connect("tcp://" + addr.getHostAddress() + ":" + port);
Which is working fine .
Now, when I remove a Server node from Proxy
repSocket.disconnect("tcp://" + addr.getHostAddress() + ":" + port);
Client gets stuck, as an request has being made and the REQ-socket waits for a response.
So the process stucks at syncclient.recvStr()
for (int request_nbr = 0; request_nbr < (request_nbr + 1); request_nbr++) {
syncclient.send(str.getBytes(),0);
System.out.println("Send Dataaaa....... " );
String data = syncclient.recvStr(Charset.defaultCharset());
System.out.println(" here.. " +data);
request_nbr++;
}
I searched and couldn't find a way to track the REQ-socket
I need any one of 2 things:
A way to keep track on a Socket-instance, which I am about to disconnect, wait till all messages are processed, so that syncclient.recvStr() will not be blocked
A way to reset the syncclient-socket, so that I can keep getting REQ/REP respond without an interruption
In real-world scenarios, rather avoid using a blocking-mode of the ZeroMQ .send() / .recv() methods and better use .poll().
While this may require a bit more SLOCs of code, the results are leaving you in a control, whereas a blocking SLOC takes all the control from your code and you cannot do much about that until ( if at all ) a next message gets delivered. That's a very wrong design practice and except the most simplistic schoolbook examples, that are actually sort of anti-patterns for the real-world.
So, do not expect Question 2 to become somehow magically solved, this is not a part of ZeroMQ API ( for many rather aloud evangelisated reasons ). Better decide between .setsockopt( ZMQ.REQ_RELAXED, 1 ), if API version and context of use permits, or do not use the trivial REQ/REP pattern at all ( due it's known risk of falling into an unsalvageable mutual dead-lock ( ref. other my posts on this very subject, where this phenomenon was both illustrated and countless times explained ) ).
In a similar manner, asking Question 1 seems reasonable in cases you have never read the ZeroMQ specifications and/or documentation and ZeroMQ "Best Practices". Having spent some time in this, your options would be crystal-clear. There are none such tools for doing this built-in. One can add some add-on, if in a need to add any similar non-core logic for her/his own need. The only setting that indirectly influences the behaviour on aSocket.close() is available in .setsockopt( ZMQ.LINGER, 0 ), which may help to prevent a system from a transition into an effective hangup-state, once aSocket waits infinitely for a state that will never happen in cases, when a message-queue is still non-empty ( messages still waiting for getting delivered ).
Going into Distributed-Systems design is like entering a new world. No sequences are guarranteed ( non-serial code execution paths happen ). No means of any local control of remote entities, their states, their failures, their presence at all, their actual ZeroMQ API version.
Indeed a challenging world to enter into.
N.b.:
You might already know, that one can .connect() aSocket-instance ( better an Access Point to aSocket-instance ) to more than one remote ends without using the proxy. With some additional .setsockopt() tuning ZMQ.IMMEDIATE to a value of 1, will help better manage the round-robin distribution policy, irrespective of the transport-classes used for the actual message delivery ( { tcp:// | ipc:// | vmci:// | pgm:// | epgm:// | inproc:// } ). All that at your fingertips.

Tikiwiki version 15.3 There is no email sent when user setup forum thread watch

I am using tiki version 15.3
I setup my preference that if there is a new forum thread that I am an editor, I will receive an email notification in "My Watches". However, I haven't received any email. It works for blog and new user registration though. So no problem with the email setup. As I debug the code, I found a few problem in the code:
In File: /lib/notification/notificationemaillib.php
Line: 112
$nots_raw = $tikilib->get_event_watches($event, $event == 'forum_post_topic'? $forum_info['forumId']: $threadId, $forum_info);
Should the $threadId is the $parentId? Since the Tiki_user_Watch table store the Thread Parent Id not the newly created threadId.
Secondly,
In line 122:
foreach ( $nots_raw as $n ) {
if ($n['user'] != $author
&& !in_array($n['user'], $users)) {
// make sure user receive only one notification even if he is monitoring both the topic and thread
$n['language'] = $tikilib->get_user_preference($n['user'], "language", $defaultLanguage);
$nots[] = $n;
$users[] = $n['user'];
}
There is no else for this if clause. I understand this condition is to send only 1 email when user monitor both thread and topic. However, I am monitoring only 1 of them, I think there should be an"
else{ $nots[] = $n;}
This way the $nots will have something to send email in the later part of the code.
if (count($nots)) {
include_once('lib/webmail/tikimaillib.php');
$smarty->assign('mail_forum', $forum_info["name"]);...
Please advise if I am wrong.
You are correct. I believe I have fixed it with this commit, which will be in the next release of version 15 (also committed to version 16, 17 and trunk).
The parent ID needed to be used instead of the thread ID as you pointed out (thanks for that - made it much easier with most of the debugging already done!). There was also an issue with identifying the existing watches properly. I don't think the if statement needs an else, but let me know if this doesn't fix it for you.

How can I get exchange rates after google retired iGoogle?

I used this link to fetch the pound to euro exchange rate on a daily (nightly) basis:
http://www.google.com/ig/calculator?hl=en&q=1pound=?euro
This returned an array which I then stripped and used the data I needed.
Since the first of November they retired iGoogle resulting in the URL to forward to: https://support.google.com/websearch/answer/2664197
Anyone knows an alternative URL that won't require me to rewrite the whole function? I'm sure google didn't stop providing this service entirely.
I started getting cronjob errors today on this very issue. So I fell back to a prior URL I was using before I switched to the faster/reliable iGoogle.
Url to programmatically hit (USD to EUR):
http://www.webservicex.net/CurrencyConvertor.asmx/ConversionRate?FromCurrency=USD&ToCurrency=EUR
Details about it:
http://www.webservicex.net/ws/WSDetails.aspx?CATID=2&WSID=10
It works for now, but its prone to be slow at times, and used to respond with an "Out of space" error randomly. Just be sure to code in a way to handle that, and maybe run the cron four times a day instead of once. I run ours every hour.
Example code to get the rate out of the return (there is probably a more elegant way):
$ci = curl_init($accessurl);
curl_setopt($ci, CURLOPT_HTTPGET, 1);
curl_setopt($ci, CURLOPT_RETURNTRANSFER, 1);
$rawreturn = curl_exec($ci);
curl_close($ci);
$rate = trim(preg_replace("/.*<double[^>]*>([^<]*)<\/double[^>]*>.*/i","$1",$rawreturn));

How do I properly impersonate another user in CoCreateInstanceEx using COAUTHIDENTITY?

I am currently working on a MFC application which needs to retrieve data from a COM object running on another system. We already have this same data exchange mechanism working and fully supported when both systems are running Windows XP and the same manually set up user account (i.e. same username and password on both systems, no domain). The trouble is that I am trying to set it up such that I can access this same DCOM system from another computer which has the same user account set up, but is logged in under a corporate Domain user account.
Right now, it works if I manually run my application using Run As and specify the alternate user, but I am looking for a better solution. When I set up the COAUTHIDENTITY for the COSERVERINFO in CoCreateInstanceEx, I specify the username and password for the alternate account, and that doesn't seem to work. I've tried various things in the Domain entry - the computer name of the local computer, of the remote computer, and leaving it blank - but none seem to help.
I tried editing the DCOM permissions for the object on the server computer to allow full access to the Everyone account, but that doesn't seem to help, and I haven't been able to find any meaningful error messages about what's really wrong. It would probably help if I could get some kind of log message on the server computer to see exactly what credentials are coming across when I run it using Run As. Does anybody have any ideas? Or maybe know what the system uses for Domain when you make a DCOM connection from a non-Domain account (a few things imply that the computer name is used, but that doesn't work when I try it).
Code follows:
COAUTHINFO AuthInfo;
COAUTHIDENTITY AuthIdentity;
COSERVERINFO ServerInfo;
MULTI_QI Results;
AuthIdentity.Domain = (unsigned short *) w_domain;
AuthIdentity.DomainLength = wcslen( w_domain);
AuthIdentity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
AuthIdentity.Password = (unsigned short *) w_password;
AuthIdentity.PasswordLength = wcslen(w_password);
AuthIdentity.User = (unsigned short *) w_username;
AuthIdentity.UserLength = wcslen(w_username);
AuthInfo.dwAuthnLevel = RPC_C_AUTHN_LEVEL_CALL;
AuthInfo.dwAuthnSvc = RPC_C_AUTHN_WINNT;
AuthInfo.dwAuthzSvc = RPC_C_AUTHZ_NONE;
AuthInfo.dwCapabilities = EOAC_NONE;
AuthInfo.dwImpersonationLevel = RPC_C_IMP_LEVEL_IMPERSONATE;
AuthInfo.pAuthIdentityData = &AuthIdentity;
AuthInfo.pwszServerPrincName = NULL;
ServerInfo.dwReserved1 = 0;
ServerInfo.dwReserved2 = 0;
ServerInfo.pAuthInfo = &AuthInfo;
ServerInfo.pwszName = w_nodename;
Results.pIID = &_uuidof(_DS_SessionContext);
Results.pItf = NULL;
Results.hr = 0;
hr = CoCreateInstanceEx(clsid, NULL, CLSCTX_ALL, &ServerInfo, (ULONG) 1, &Results);
if(FAILED(hr))
{
m_Error.Format("(0x%x) CoCreateInstanceEx for _DS_DataFrame failed.",hr);
m_Error2.Format("Make sure computer IP address is correct and connected.");
CoUninitialize();
UpdateData(false);
UpdateWindow();
return false;
}
pSession = (_DS_SessionContext *)Results.pItf;
hr = pSession->raw_DS_GetVersion(&DSStatus, &version);
if(FAILED(hr))
{
m_Error.Format("(0x%x)GetVersion",hr);
CoUninitialize();
UpdateData(false);
UpdateWindow();
return false;
}
Ah, I figured it out. Turns out that in DCOM, creating the instance and calling functions on it do not automatically use the same security blanket. The authentication info in the COSERVERINFO passed to CoCreateInstanceEx only applies towards creating the instance, and when I call functions on that instance later, then it fails because I am calling those functions using the credentials of the application.
To do it properly, before calling functions on the instance, I must first call (error handling omitted for clarity):
hr = CoSetProxyBlanket(Results.pItf, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL,
RPC_C_IMP_LEVEL_IMPERSONATE, &AuthIdentity, EOAC_NONE);
This sets the security blanket used to call the instance to the same one that was used to create it, and thus everything works.