/*
 * maxcalc.c — DF-0935 disproof: compute the maximum possible output of
 * procfs_dorlimit under three cap scenarios. All stay under 512.
 *
 * Build: cc -o maxcalc maxcalc.c
 * Run:   ./maxcalc
 */
#include <stdio.h>
#include <sys/resource.h>
#include <string.h>

static const char *ident[] = {
    "cpu","fsize","data","stack","core","rss","memlock",
    "nproc","nofile","sbsize","vmem","posixlock"
};

static int ndig(unsigned long long v) {
    int n = 1;
    while (v >= 10) { v /= 10; n++; }
    return n;
}

int main(void) {
    unsigned long long rlt = (unsigned long long)RLIM_INFINITY - 1; /* 19 digits */
    unsigned long long imax = 2147483647ULL;                        /* 10 digits */
    unsigned long long mds = 32ULL*1024*1024*1024;                   /* MAXDSIZ default, 11 digits */
    unsigned long long mss = 512ULL*1024*1024;                       /* MAXSSIZ default, 9 digits */

    /* Scenario C: default config, user maximally inflates */
    unsigned long long sC[12] = {
        rlt,rlt,mds,mss,rlt,rlt,rlt, 2033, 32528, rlt,rlt, 32528
    };
    /* Scenario B: maxdsiz+maxssiz raised to RLIM_INFINITY-1, others default */
    unsigned long long sB[12] = {
        rlt,rlt,rlt,rlt,rlt,rlt,rlt, 2033, 32528, rlt,rlt, 32528
    };
    /* Scenario A: every achievable cap maxed (maxdsiz+maxssiz = RLIM_INFINITY-1,
       3 int caps = INT_MAX), user sets every uncapped resource to RLIM_INFINITY-1 */
    unsigned long long sA[12] = {
        rlt,rlt,rlt,rlt,rlt,rlt,rlt, imax, imax, rlt,rlt, imax
    };

    printf("rlim_t max = %llu (%d digits)\n", rlt, ndig(rlt));
    printf("INT_MAX    = %llu (%d digits)\n", imax, ndig(imax));
    printf("MAXDSIZ    = %llu (%d digits)\n", mds, ndig(mds));
    printf("MAXSSIZ    = %llu (%d digits)\n\n", mss, ndig(mss));

    size_t tA=0, tB=0, tC=0;
    int i;
    for (i = 0; i < 12; i++) {
        tA += strlen(ident[i]) + 1 + 2*ndig(sA[i]) + 2;
        tB += strlen(ident[i]) + 1 + 2*ndig(sB[i]) + 2;
        tC += strlen(ident[i]) + 1 + 2*ndig(sC[i]) + 2;
    }
    printf("Scenario A (every achievable cap maxed):               %4zu bytes  -> %s\n",
           tA, tA > 512 ? "OVERFLOW" : "UNDER 512");
    printf("Scenario B (maxdsiz+maxssiz raised, others default):   %4zu bytes  -> %s\n",
           tB, tB > 512 ? "OVERFLOW" : "UNDER 512");
    printf("Scenario C (default config, user maximally inflates):  %4zu bytes  -> %s\n",
           tC, tC > 512 ? "OVERFLOW" : "UNDER 512");
    return 0;
}
