/* cpufreq.c version 0.1
 *
 * a suid capable wrapper for linux 2.4 and linux 2.6 cpu frequency
 * scaling stuff[tm]
 *
 * (C) 2005-04-30 Georg Lukas <georg@boerde.de>
 * This program is available under the GPL license.
 */

#include <errno.h>
#include <stdio.h>

#define OUT24 "/proc/acpi/processor/CPU0/performance"
#define OUT26 "/sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed"
#define OUTBUFSIZE 9

int main(int argc, char **argv) {
	char *filename = NULL;
	int mhz = -1;
	char outbuf[OUTBUFSIZE];
	FILE *fout;

	if (argc >= 3) {
		mhz = atoi(argv[2]);
		if (0 == strncmp(argv[1], "2.4", 3)) {
			filename = OUT24;
			switch (mhz) {
			case  600: strncpy(outbuf, "4\n", OUTBUFSIZE); break;
			case  800: strncpy(outbuf, "3\n", OUTBUFSIZE); break;
			case 1000: strncpy(outbuf, "2\n", OUTBUFSIZE); break;
			case 1200: strncpy(outbuf, "1\n", OUTBUFSIZE); break;
			case 1300: strncpy(outbuf, "0\n", OUTBUFSIZE); break;
			default:
				fprintf(stderr, "Illegal frequency: %s\n", argv[2]);
				exit(3);
			}
		} else if (0 == strncmp(argv[1], "2.6", 3)) {
			filename = OUT26;
			if (mhz != 0) {
				snprintf(outbuf, OUTBUFSIZE, "%i000\n", mhz);
			} else {
				fprintf(stderr, "Illegal frequency: %s\n", argv[2]);
				exit(3);
			}
		} else {
			fprintf(stderr, "Supported kernel versions are: 2.4 2.6\n");
			return 2;
		}
		fout = fopen(filename, "w");
		if (!fout) {
			fprintf(stderr, "fopen(%s): %s\n", filename, strerror(errno));
			return 1;
		}
		fprintf(fout, "%s\n", outbuf);
		fclose(fout);
	} else {
		fprintf(stderr, "Syntax: %s <kernel version> <value>\n", argv[0]);
	}
	return 0;
}
