// File: spjmurray[P]nagios-plugin-check-scsi-smart/check_scsi_smart.cc
// Function: check_smart_attributes(int, std::map<unsigned char, unsigned long, std::less<unsigned char>, std::allocator<std::pair<unsigned char const, unsigned long>>>&, std::map<unsigned char, unsigned long, std::less<unsigned char>, std::allocator<std::pair<unsigned char const, unsigned long>>>&, int&, int&, int&, int&, int&, std::ostream&)
void check_smart_attributes(int fd, SmartThresholdMap& critical_thresholds, SmartThresholdMap& warning_thresholds,
                            int& code, int& prdfail, int& advisory, int& crit, int& warn, ostream& perfdata) {

  // Load the SMART data and thresholds pages
  smart_data sd;
  ata_smart_read_data(fd, reinterpret_cast<unsigned char*>(&sd));

  smart_thresholds st;
  ata_smart_read_thresholds(fd, reinterpret_cast<unsigned char*>(&st));

  // Perform actual SMART threshold checks
  for(int i=0; i<SMART_ATTRIBUTE_NUM; i++) {

    SmartAttribute attribute(sd.attributes[i]);
    SmartThreshold threshold(st.thresholds[i]);

    if(!attribute.idValid())
      continue;

    // Check the validity of the attribute value and whether the threshold has been exceeded
    if(attribute.valueValid() && (attribute <= threshold)) {

      // Predicted failure is within 24 hours, otherwise the device lifespan has been exceeded
      if(attribute.getPreFail())
        prdfail++;
      else
        advisory++;

    }

    // Check against custom raw thresholds
    uint64_t crit_threshold = critical_thresholds[attribute.getID()];
    uint64_t warn_threshold = warning_thresholds[attribute.getID()];

    if(crit_threshold && (attribute.getRaw() >= crit_threshold)) {
      crit++;
    } else if(warn_threshold && (attribute.getRaw() >= warn_threshold)) {
      warn++;
    }

    // Accumulate the performance data
    perfdata << " " << attribute << ";";
    if(warn_threshold)
      perfdata << warn_threshold;
    perfdata << ";";
    if(crit_threshold)
      perfdata << crit_threshold;
    perfdata << ";;";

  }

  // Determine the state to report
  if(advisory || warn)
    code = max(code, NAGIOS_WARNING);

  if(prdfail || crit)
    code = max(code, NAGIOS_CRITICAL);

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x480, %rsp            # imm = 0x480
movq 0x20(%rbp), %rax
movq 0x18(%rbp), %rax
movq 0x10(%rbp), %rax
movl %edi, -0x4(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq %r9, -0x30(%rbp)
movl -0x4(%rbp), %edi
leaq -0x230(%rbp), %rsi
callq 0x4930
movl -0x4(%rbp), %edi
leaq -0x430(%rbp), %rsi
callq 0x49e0
movl $0x0, -0x434(%rbp)
cmpl $0x1e, -0x434(%rbp)
jge 0x4e0b
leaq -0x230(%rbp), %rsi
addq $0x2, %rsi
movslq -0x434(%rbp), %rax
imulq $0xc, %rax, %rax
addq %rax, %rsi
leaq -0x448(%rbp), %rdi
callq 0x8280
leaq -0x430(%rbp), %rsi
addq $0x2, %rsi
movslq -0x434(%rbp), %rax
imulq $0xc, %rax, %rax
addq %rax, %rsi
leaq -0x449(%rbp), %rdi
callq 0x84a0
leaq -0x448(%rbp), %rdi
callq 0x5bc0
testb $0x1, %al
jne 0x4c52
jmp 0x4df7
leaq -0x448(%rbp), %rdi
callq 0x5be0
testb $0x1, %al
jne 0x4c64
jmp 0x4ca9
leaq -0x448(%rbp), %rdi
leaq -0x449(%rbp), %rsi
callq 0x83d0
testb $0x1, %al
jne 0x4c7d
jmp 0x4ca9
leaq -0x448(%rbp), %rdi
callq 0x5c20
testb $0x1, %al
jne 0x4c8f
jmp 0x4c9c
movq -0x28(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
jmp 0x4ca7
movq -0x30(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
jmp 0x4ca9
movq -0x10(%rbp), %rax
movq %rax, -0x480(%rbp)
leaq -0x448(%rbp), %rdi
callq 0x5d20
movq -0x480(%rbp), %rdi
movb %al, -0x459(%rbp)
leaq -0x459(%rbp), %rsi
callq 0x5c40
movq (%rax), %rax
movq %rax, -0x458(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x478(%rbp)
leaq -0x448(%rbp), %rdi
callq 0x5d20
movq -0x478(%rbp), %rdi
movb %al, -0x469(%rbp)
leaq -0x469(%rbp), %rsi
callq 0x5c40
movq (%rax), %rax
movq %rax, -0x468(%rbp)
cmpq $0x0, -0x458(%rbp)
je 0x4d49
leaq -0x448(%rbp), %rdi
callq 0x5d30
cmpq -0x458(%rbp), %rax
jb 0x4d49
movq 0x10(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
jmp 0x4d75
cmpq $0x0, -0x468(%rbp)
je 0x4d73
leaq -0x448(%rbp), %rdi
callq 0x5d30
cmpq -0x468(%rbp), %rax
jb 0x4d73
movq 0x18(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
jmp 0x4d75
movq 0x20(%rbp), %rdi
leaq 0x455e(%rip), %rsi      # 0x92de
callq 0x4200
movq %rax, %rdi
leaq -0x448(%rbp), %rsi
callq 0x8410
movq %rax, %rdi
leaq 0x44f5(%rip), %rsi      # 0x9293
callq 0x4200
cmpq $0x0, -0x468(%rbp)
je 0x4dbd
movq 0x20(%rbp), %rdi
movq -0x468(%rbp), %rsi
callq 0x4070
movq 0x20(%rbp), %rdi
leaq 0x44cb(%rip), %rsi      # 0x9293
callq 0x4200
cmpq $0x0, -0x458(%rbp)
je 0x4de7
movq 0x20(%rbp), %rdi
movq -0x458(%rbp), %rsi
callq 0x4070
movq 0x20(%rbp), %rdi
leaq 0x44a0(%rip), %rsi      # 0x9292
callq 0x4200
movl -0x434(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x434(%rbp)
jmp 0x4be6
movq -0x30(%rbp), %rax
cmpl $0x0, (%rax)
jne 0x4e1d
movq 0x18(%rbp), %rax
cmpl $0x0, (%rax)
je 0x4e35
movq -0x20(%rbp), %rdi
leaq 0x4264(%rip), %rsi      # 0x908c
callq 0x5d50
movl (%rax), %ecx
movq -0x20(%rbp), %rax
movl %ecx, (%rax)
movq -0x28(%rbp), %rax
cmpl $0x0, (%rax)
jne 0x4e47
movq 0x10(%rbp), %rax
cmpl $0x0, (%rax)
je 0x4e5f
movq -0x20(%rbp), %rdi
leaq 0x423e(%rip), %rsi      # 0x9090
callq 0x5d50
movl (%rax), %ecx
movq -0x20(%rbp), %rax
movl %ecx, (%rax)
addq $0x480, %rsp            # imm = 0x480
popq %rbp
retq
nopl (%rax,%rax)