#!/usr/bin/env python
"""
   Send SNMP trap to remote SNMP manager.

   Copyright 1999-2004 by Ilya Etingof <ilya@glas.net>. See LICENSE for
   details.
"""
from sys import exit, argv, stderr
from string import find

from pysnmp.version import verifyVersionRequirement
verifyVersionRequirement(3, 4)

from pysnmp.mapping.udp.role import Manager
from pysnmp.proto.api import alpha
from pysnmpap.cli import options, ucd
from pysnmpap.error import SnmpApplicationError

class ConfSnmpVersion(options.ConfOptionValue):
    def help(self): return 'SNMP protocol version to use [%s]' % self
confSnmpVersion = ConfSnmpVersion(alpha.protoVersionId1)    

class ConfReportType(options.ConfOptionFlag):
    def help(self): return 'report variables types [%s]' % self
confReportType = ConfReportType(0)

def formatUsage():
    tspDsp = Manager()
    ver = alpha.protoVersions[confSnmpVersion()]
    req = ver.Message()
    req.apiAlphaSetPdu(ver.TrapPdu())
    appUsage = '[ -h ] [ -v <version> ] [ -C <t> ]'
    appOpts =           ' -h             print this usage note.\n'
    appOpts = appOpts + ' -v <version>   ' + confSnmpVersion.help() + '\n'
    appOpts = appOpts + ' -C <t>         application specific options\n'
    appOpts = appOpts + '     t:         ' + confReportType.help() + '\n'
    usage = 'Usage: ' + argv[0] + ' ' + appUsage + ' ' + \
            tspDsp.cliUcdGetUsage() + ' ' + req.cliUcdGetUsage()
    options = 'Application options:\n' + appOpts + \
              'Transport options:\n' + tspDsp.cliUcdGetOptsUsage(' ') + \
              'Protocol options:\n' + req.cliUcdGetOptsUsage()
    return usage + '\n' + options

# Parse app options
idx = 1; newArgv = []
while idx < len(argv):
    if argv[idx] == '-h':
        stderr.write(formatUsage() + '\n')
        exit(1)
    if argv[idx] == '-v':
        if argv[idx+1][:1] != 'v': argv[idx+1] = 'v'+argv[idx+1]
        if argv[idx+1] == 'v1':
            confSnmpVersion(alpha.protoVersionId1)
        elif argv[idx+1] == 'v2c':
            confSnmpVersion(alpha.protoVersionId2c)
        else:
            stderr.write('Unsupported SNMP protocol version: %s\n%s\n' % \
                         (argv[idx+1], formatUsage()))
            exit(-1)
        idx = idx + 2
        continue
    if argv[idx] == '-C':
        try:
            for c in list(argv[idx+1]):
                if c == 't': confReportType(1)
        except IndexError, why:
            stderr.write('Missing value to %s\n%s\n' % \
                         (argv[idx], formatUsage()))
            exit(-1)
        idx = idx + 2
        continue
    newArgv.append(argv[idx])
    idx = idx + 1

# Proto & transport objects
tspDsp = Manager()
ver = alpha.protoVersions[confSnmpVersion()]
req = ver.Message(); rsp = ver.Message()
req.apiAlphaSetPdu(ver.TrapPdu())

# Parse transport and protocol options
try:
    newArgv = req.cliUcdSetArgs(tspDsp.cliUcdSetArgs(newArgv))
except SnmpApplicationError, why:
    stderr.write('Error: %s\n%s\n' % (why, formatUsage()))
    exit(-1)

if len(newArgv):
    stderr.write('Extra parameters given: %s\n%s\n' \
                 % (newArgv, formatUsage()))
    exit(-1)

try:
    tspDsp.send(req.berEncode())

except SnmpApplicationError, why:
    if why: stderr.write('Application error: %s\n' % why)
    exit(-1)

except Exception, why:
    stderr.write('pysnmp error: %s\n' % why)
    exit(-1)
