#! /bin/bash
-# Expecting message text on stdin.
-# TODO: make it smart.
-mail -s 'notify-message' root
\ No newline at end of file
+######################################################################
+test "$1" = "--help" && {
+cat <<EOF
+Usage: notify-message [-p PACKAGE]
+
+Per default zypp invokes this command to propagate update
+notification messages. The optional -p argument should
+denote the packages that causes this message to be sent.
+The message text itself is read from stdin.
+
+See update.messages.notify option in /etc/zypp.conf
+for details.
+EOF
+exit 0;
+}
+######################################################################
+
+MAILCMD="/usr/bin/mail"
+test -x "$MAILCMD" || {
+ echo "notify-message: $MAILCMD: command not found" >&2
+ exit 1;
+}
+
+MAILTAG="[zypp-notify-message]"
+MAIL_TO="root"
+# curently just '-p packageident'
+test "$1" = "-p" && {
+ MAILTAG="$MAILTAG $2"
+}
+
+exec $MAILCMD -s "$MAILTAG" $MAIL_TO
}
}
+ inline std::string notificationCmdSubst( const std::string & cmd_r, const UpdateNotificationFile & notification_r )
+ {
+ std::string ret( cmd_r );
+#define SUBST_IF(PAT,VAL) if ( ret.find( PAT ) != std::string::npos ) ret = str::gsub( ret, PAT, VAL )
+ SUBST_IF( "%p", notification_r.solvable().asString() );
+ SUBST_IF( "%P", notification_r.file().asString() );
+#undef SUBST_IF
+ return ret;
+ }
+
void sendNotification( const Pathname & root_r,
- const Pathname & messagesPath_r,
const UpdateNotifications & notifications_r )
{
if ( notifications_r.empty() )
return;
}
- std::vector<std::string> command;
- command.push_back( "<" ); // prepare to redirect input
- str::splitEscaped( commandStr, std::back_inserter( command ) );
-
// Take care: commands are ececuted chroot(root_r). The message file
// pathnames in notifications_r are local to root_r. For physical access
// to the file they need to be prefixed.
{
for_( it, notifications_r.begin(), notifications_r.end() )
{
+ std::vector<std::string> command;
if ( format == SINGLE )
- command.front() = "<"+Pathname::assertprefix( root_r, it->file() ).asString();
+ command.push_back( "<"+Pathname::assertprefix( root_r, it->file() ).asString() );
+ str::splitEscaped( notificationCmdSubst( commandStr, *it ), std::back_inserter( command ) );
+
ExternalProgram prog( command, ExternalProgram::Stderr_To_Stdout, false, -1, true, root_r );
if ( true ) // Wait for feedback
{
}
}
- command.front() = "<"+tmpfile.path().asString(); // redirect input
+ std::vector<std::string> command;
+ command.push_back( "<"+tmpfile.path().asString() ); // redirect input
+ str::splitEscaped( notificationCmdSubst( commandStr, *notifications_r.begin() ), std::back_inserter( command ) );
+
ExternalProgram prog( command, ExternalProgram::Stderr_To_Stdout, false, -1, true, root_r );
if ( true ) // Wait for feedback otherwise the TmpFile goes out of scope.
{
historylog.comment( str::Str() << _("New update message") << " " << localPath, /*timestamp*/true );
}
}
- sendNotification( root_r, messagesPath_r, result_r.updateMessages() );
+ sendNotification( root_r, result_r.updateMessages() );
}
/////////////////////////////////////////////////////////////////